package com.jun.generator.core;

import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.querys.MySqlQuery;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.keywords.MySqlKeyWordsHandler;
import tk.mybatis.mapper.common.Mapper;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author yuejun.li
 * @date 2024/4/29 10:51:25
 * 逆向工程核心类
 */
public class GeneratorCore {
    public static void create(GeneratorCore.Param param) {
        //使用mybatis-plus依赖的fastAutoGenerator类去构建
        FastAutoGenerator.create(param.url, param.userName, param.password).dataSourceConfig((builder) -> {
            //dbQuery数据库查询、typeConvert数据库类型转换器、keyWordsHandler数据库关键字处理器
            builder.dbQuery(new MySqlQuery()).typeConvert(new MySqlTypeConvert()).keyWordsHandler(new MySqlKeyWordsHandler()).build();
        }).globalConfig((builder) -> {
            //作者名、开启swagger、指定输出目录
            builder.author(param.author).enableSwagger().outputDir(param.baseDir);
        }).packageConfig((builder) -> {
            //父包名、service名、serviceImpl名、对象包名、mapper包名（可以把Controller也加上）
            builder.parent(param.basePackageName).service("service" + param.db).serviceImpl("service.impl." + param.db).entity("model").mapper("mapper").pathInfo(outputFileStringMap(param.baseDir, param.provider, param.project, param.packageDir));
        }).templateConfig((builder) -> {
            //模板
            builder.controller("").serviceImpl("").service("");
        }).strategyConfig((builder) -> {
            //entity：开启常量字段、开启链式编程、开启lombok、开启字段注解、开启覆盖已有文件
            //service：格式化Service、ServiceImpl的名字、开启覆盖已有文件
            //mapper：开启覆盖已有文件、父类mapper引用tk.mapper的Mapper.class(不然没有Example)
            builder.entityBuilder().enableChainModel().enableColumnConstant().enableLombok().enableTableFieldAnnotation().enableFileOverride();
            builder.serviceBuilder().formatServiceFileName("%s").formatServiceImplFileName("%sImpl").enableFileOverride();
            builder.mapperBuilder().superClass(Mapper.class).enableFileOverride();
            builder.addInclude(param.tables);
        }).templateEngine(new FreemarkerTemplateEngine()).execute();
    }

    /**
     * 生成对象类、mapper类、xml的路径
     * @param baseDir
     * @param provider
     * @param project
     * @param packageDir
     * @return
     */
    private static Map<OutputFile, String> outputFileStringMap(String baseDir, String provider, String project, String packageDir) {
        Map<OutputFile, String> outputFileStringMap = new HashMap();
        outputFileStringMap.put(OutputFile.entity, baseDir + "\\" + provider + "\\src\\main\\java\\" + packageDir + "\\" + project + "\\model");
        outputFileStringMap.put(OutputFile.mapper, baseDir + "\\" + provider + "\\src\\main\\java\\" + packageDir + "\\" + project + "\\mapper");
        outputFileStringMap.put(OutputFile.xml, baseDir + "\\" + provider + "\\src\\main\\resources\\mapper\\core\\default");
        return outputFileStringMap;
    }

    /**
     * 参数
     */
    public static class Param {
        //基本路径
        String baseDir;
        //数据库
        String db;
        //基本包名称
        String basePackageName;
        //作者
        String author;
        //数据库url
        String url;
        //数据库账号
        String userName;
        //数据库密码
        String password;
        //表名
        List<String> tables;
        //
        String provider;
        //项目名
        String project;
        //包的路径
        String packageDir;

        public String getBaseDir() {
            return baseDir;
        }

        public void setBaseDir(String baseDir) {
            this.baseDir = baseDir;
        }

        public String getDb() {
            return db;
        }

        public void setDb(String db) {
            this.db = db;
        }

        public String getBasePackageName() {
            return basePackageName;
        }

        public void setBasePackageName(String basePackageName) {
            this.basePackageName = basePackageName;
        }

        public String getAuthor() {
            return author;
        }

        public void setAuthor(String author) {
            this.author = author;
        }

        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }

        public String getUserName() {
            return userName;
        }

        public void setUserName(String userName) {
            this.userName = userName;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }

        public List<String> getTables() {
            return tables;
        }

        public void setTables(List<String> tables) {
            this.tables = tables;
        }

        public String getProvider() {
            return provider;
        }

        public void setProvider(String provider) {
            this.provider = provider;
        }

        public String getProject() {
            return project;
        }

        public void setProject(String project) {
            this.project = project;
        }

        public String getPackageDir() {
            return packageDir;
        }

        public void setPackageDir(String packageDir) {
            this.packageDir = packageDir;
        }
    }
}
